package io.xjar.demo;

import io.xjar.XCryptos;
import io.xjar.XPluginManager;

import java.io.File;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;

/**
 * 动态插件加载演示程序
 * 展示如何构建和加密三个Spring Boot项目(base-project, plugin-a, plugin-b)并实现动态插件加载
 */
public class DynamicPluginDemo {

    // 项目路径配置
    private static final String PROJECT_BASE = "target/demo";
    private static final String BASE_JAR = PROJECT_BASE + "/base-project.jar";
    private static final String PLUGIN_A_JAR = PROJECT_BASE + "/plugin-a.jar";
    private static final String PLUGIN_B_JAR = PROJECT_BASE + "/plugin-b.jar";
    private static final String ENCRYPTED_DIR = PROJECT_BASE + "/encrypted";
    private static final String PLUGIN_DIR = ENCRYPTED_DIR + "/plugins";

    public static void main(String[] args) {
        try {
            System.out.println("开始演示动态插件加载功能...");

            // 1. 创建示例项目JAR文件
            createSampleProjects();

            // 2. 加密项目
            encryptProjects();

            // 3. 演示动态插件加载
            demonstratePluginLoading();

            System.out.println("演示完成!");
        } catch (Exception e) {
            System.err.println("演示过程中发生错误: " + e.getMessage());
            e.printStackTrace();
        }
    }

    /**
     * 创建示例项目JAR文件
     */
    private static void createSampleProjects() throws Exception {
        System.out.println("1. 创建示例项目JAR文件...");

        // 创建目录
        Files.createDirectories(Paths.get(PROJECT_BASE));

        // 创建基座项目
        String baseContent = "Base Project JAR\n" +
                "Contains: \n" +
                "- com/framework/Application.class\n" +
                "- com/framework/Service.class\n" +
                "- application.yml\n";
        Files.write(Paths.get(BASE_JAR), baseContent.getBytes());
        System.out.println("   创建基座项目: " + BASE_JAR);

        // 创建插件A
        String pluginAContent = "Plugin A JAR\n" +
                "Contains: \n" +
                "- com/plugin/a/PluginA.class\n" +
                "- com/plugin/a/ServiceA.class\n";
        Files.write(Paths.get(PLUGIN_A_JAR), pluginAContent.getBytes());
        System.out.println("   创建插件A项目: " + PLUGIN_A_JAR);

        // 创建插件B
        String pluginBContent = "Plugin B JAR\n" +
                "Contains: \n" +
                "- com/plugin/b/PluginB.class\n" +
                "- com/plugin/b/ServiceB.class\n";
        Files.write(Paths.get(PLUGIN_B_JAR), pluginBContent.getBytes());
        System.out.println("   创建插件B项目: " + PLUGIN_B_JAR);
    }

    /**
     * 加密项目
     */
    private static void encryptProjects() throws Exception {
        System.out.println("2. 加密项目...");

        // 创建输出目录
        Files.createDirectories(Paths.get(ENCRYPTED_DIR));
        Files.createDirectories(Paths.get(PLUGIN_DIR));

        // 加密基座项目
        System.out.println("   加密基座项目...");
        XCryptos.encryption()
                .from(BASE_JAR)
                .password("base-password")
                .include("com/framework/**")
                .to(ENCRYPTED_DIR, "base.jar");

        // 加密插件A (标记为插件模式)
        System.out.println("   加密插件A...");
        XCryptos.encryption()
                .from(PLUGIN_A_JAR)
                .password("plugin-a-password")
                .asPlugin()
                .to(PLUGIN_DIR, "plugin-a.jar");

        // 加密插件B (标记为插件模式)
        System.out.println("   加密插件B...");
        XCryptos.encryption()
                .from(PLUGIN_B_JAR)
                .password("plugin-b-password")
                .asPlugin()
                .to(PLUGIN_DIR, "plugin-b.jar");

        System.out.println("   所有项目加密完成");
    }

    /**
     * 演示插件动态加载
     */
    private static void demonstratePluginLoading() throws Exception {
        System.out.println("3. 演示动态插件加载...");

        // 创建插件管理器
        XPluginManager pluginManager = new XPluginManager(
                PLUGIN_DIR,
                DynamicPluginDemo.class.getClassLoader(),
                null, // 实际使用中需要提供正确的解密器
                null, // 加密器
                null  // 密钥
        );

        // 加载插件
        System.out.println("   扫描并加载插件...");
        pluginManager.loadPlugins();

        // 显示加载的插件
        System.out.println("   加载的插件数量: " + pluginManager.getPlugins().size());
        for (XPluginManager.Plugin plugin : pluginManager.getPlugins()) {
            System.out.println("   - " + plugin.getName() + " (" + plugin.getJarFile().getAbsolutePath() + ")");
        }

        System.out.println("   插件加载演示完成");
    }
}